package com.sd365.permission.centre.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.sd365.common.core.annotation.stuffer.CommonFieldStuffer;
import com.sd365.common.core.annotation.stuffer.IdGenerator;
import com.sd365.common.core.annotation.stuffer.MethodTypeEnum;
import com.sd365.common.core.common.aop.MyPageInfo;
import com.sd365.common.core.common.exception.BusinessException;
import com.sd365.common.core.common.exception.code.BusinessErrorCode;
import com.sd365.common.core.context.BaseContextHolder;
import com.sd365.common.util.BeanException;
import com.sd365.common.util.BeanUtil;
import com.sd365.permission.centre.dao.mapper.ResourceMapper;
import com.sd365.permission.centre.dao.mapper.RoleMapper;
import com.sd365.permission.centre.dao.mapper.RoleResourceMapper;
import com.sd365.permission.centre.entity.Resource;
import com.sd365.permission.centre.pojo.dto.ResourceDTO;
import com.sd365.permission.centre.pojo.dto.SubSystemDTO;
import com.sd365.permission.centre.pojo.query.ResourceQuery;
import com.sd365.permission.centre.pojo.vo.ResourceVO;
import com.sd365.permission.centre.service.ResourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class ResourceServiceImpl extends AbstractBaseDataServiceImpl implements ResourceService {

    @Autowired
    private ResourceMapper resourceMapper;

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RoleResourceMapper roleResourceMapper;

    @Autowired
    private RoleMapper roleMapper;

    /**
     * 初始化缓存
     * @param resourceQuery
     * @return
     */
    @Override
    public List<ResourceDTO> initRedis(ResourceQuery resourceQuery) {
        List<Resource> resources = resourceMapper.commonQuery(resourceQuery);
        log.info("resources---------->{}",resources);
        for(Resource resource : resources){
            if(redisTemplate.opsForValue().get(resource.getId().toString()) == null){
                redisTemplate.opsForValue().set(resource.getId().toString(),resource);
            }
            else {
                continue;
            }
        }
        List<ResourceDTO> resourceDTOS = BeanUtil.copyList(resources,ResourceDTO.class);
        return resourceDTOS;
    }

    @Override
    @CommonFieldStuffer(methodType = MethodTypeEnum.QUERY)

    public List<ResourceDTO> commonQuery(ResourceQuery resourceQuery) {

        if (resourceQuery == null) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("commonQuery 方法错误"));
        }

        List<Resource> resources = resourceMapper.commonQuery(resourceQuery);
        if (resources != null && !resources.isEmpty()) {
            Page page = (Page) resources;
            BaseContextHolder.set("pageInfo", JSON.toJSONString(new MyPageInfo(page.getTotal(), page.getPages())));
            List<ResourceDTO> resourceDTOS = BeanUtil.copyList(resources, ResourceDTO.class, new BeanUtil.CopyCallback() {
                @Override
                public void copy(Object o, Object o1) {
                    Resource resource1 = (Resource) o;
                    ResourceDTO resourceDTO = (ResourceDTO) o1;
                    if (resource1.getResource() != null) {
                        ResourceDTO copy = BeanUtil.copy(resource1.getResource(), ResourceDTO.class);
                        resourceDTO.setResourceDTO(copy);
                    }
                    if (resource1.getSubSystem() != null) {
                        BeanUtil.copy(resource1.getSubSystem(), resourceDTO.getSubSystem(), SubSystemDTO.class);
                    }
                }
            });
            return resourceDTOS;
        } else {
            return new ArrayList<>();
        }

    }



    @Override
    public List<ResourceDTO> query(ResourceQuery resourceQuery) {

        if (resourceQuery == null) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("commonQuery 方法错误"));
        }
        List<Resource> resources = resourceMapper.commonQuery(resourceQuery);
        Page page = (Page) resources;
        BaseContextHolder.set("pageInfo", JSON.toJSONString(new MyPageInfo(page.getTotal(), page.getPages())));
        List<ResourceDTO> resourceDTOS = BeanUtil.copyList(resources, ResourceDTO.class);
        return resourceDTOS;
    }

    @Override
    public ResourceVO add(ResourceDTO resourceDTO) {
        if (resourceDTO == null) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("commonQuery 方法错误"));
        }
        Resource resource = BeanUtil.copy(resourceDTO, Resource.class);
        //调用雪花计算ID
        resource.setId(idGenerator.snowflakeId());

        if( resourceMapper.insert(resource)>0 ){
            return BeanUtil.copy(resource, ResourceVO.class);
        }else return null;
    }

    @Override
    @CommonFieldStuffer(methodType = MethodTypeEnum.DELETE)
    public Boolean batchDelete(ResourceDTO[] resourceDTOS) {
        if (resourceDTOS.length == 0) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("batchDelete 方法错误"));
        }
        for (ResourceDTO resourceDTO : resourceDTOS) {
            Example example = new Example(Resource.class);
            example.createCriteria().andEqualTo("id", resourceDTO.getId());
            int result = resourceMapper.deleteByExample(example);
            if (result <= 0) {
                throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_OTHER_EXCEPTION, new Exception(String.format("删除的记录id %d 没有匹配到版本", resourceDTO.getId())));
            }
        }
        return true;
    }

    @Override
    @CommonFieldStuffer(methodType = MethodTypeEnum.DELETE)
    public Boolean remove(Long id) {
        Example example = new Example(Resource.class);
        example.createCriteria().andEqualTo("id", id);
        return resourceMapper.deleteByExample(example) > 0;

    }

    @Override
    public ResourceVO modify(ResourceDTO resourceDTO) {
        Resource resource = BeanUtil.copy(resourceDTO, Resource.class);


        super.baseDataStuff4Updated(resource);
        if (resourceDTO.getVersion() != null) {
            Long version = resourceDTO.getVersion();
            resource.setVersion(version++);
        }

        Example example = new Example(Resource.class);
        example.createCriteria().andEqualTo("id", resourceDTO.getId());
        if(resourceMapper.updateByExampleSelective(resource, example) > 0){
            return BeanUtil.copy(resource,ResourceVO.class);
        }else {
            return null;
        }
    }

    @Override
    public ResourceDTO copy(Long id) {
        if (null == id) {
            throw new RuntimeException("传输参数为空异常:copy方法");
        }
        /**
         查询 id的客户信息
         修改 id 插入行的客户信息
         */
        try {
            Resource resource = resourceMapper.selectByPrimaryKey(id);
            if (resource != null) {
                resource.setId(idGenerator.snowflakeId());
                if (resourceMapper.insert(resource) > 0) {
                    ResourceDTO resourceDTO = BeanUtil.copy(resource, ResourceDTO.class);
                    return resourceDTO;
                } else {
                    throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("copy 方法错误"));
                }
            } else {
                throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("错误"));
            }
        } catch (BeanException ex) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_BEAN_COPY_EXCEPTION, ex);
        } catch (Exception ex) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("错误"));
        }
    }

    @Override
    public ResourceDTO queryById(Long id) {


        log.info("public ResourceDTO queryById(Long id) 请求参数：{}", id);
        Resource byId = resourceMapper.findById(id);
        if (byId == null) {
            return new ResourceDTO();
        }
        log.info("public ResourceDTO queryById(Long id) 重新参数：{}", byId);
        ResourceDTO resourceDTO = BeanUtil.copy(byId, ResourceDTO.class);

        if (byId.getSubSystem() != null) {
            SubSystemDTO copy = BeanUtil.copy(byId.getSubSystem(), SubSystemDTO.class);
            resourceDTO.setSubSystem(copy);

        }
        if (byId.getResource() != null) {
            ResourceDTO copy = BeanUtil.copy(byId.getResource(), ResourceDTO.class);
            resourceDTO.setResourceDTO(copy);

        }
        log.info("public ResourceDTO queryById(Long id) 返回参数：{}", resourceDTO);
        return resourceDTO;
    }

    @Override
    public ResourceDTO findByParentId(Long id) {

        ResourceDTO resourceDTO = BeanUtil.copy(resourceMapper.findByParentId(id), ResourceDTO.class);

        return resourceDTO;
    }

    @Override
    public List<ResourceDTO> queryResourceByMenu() {
        Example example = new Example(Resource.class);
        example.createCriteria().andEqualTo("resourceType", (byte) 0);
        List<Resource> resources = resourceMapper.selectByExample(example);
        return BeanUtil.copyList(resources, ResourceDTO.class);

    }
}
